package cn.kwq.project_manger.handler;

import cn.dev33.satoken.exception.NotLoginException;
import cn.hutool.json.JSONException;
import cn.kwq.project_manger.common.E;
import cn.kwq.project_manger.exception.RequestLimitException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;

@ControllerAdvice
@Slf4j
public class ErrorHandler {
    /**
     * 全局异常拦截（拦截项目中的NotLoginException异常）
     */
    @ResponseBody
    @ExceptionHandler(value = NotLoginException.class)
    public Map handlerNotLoginException(HttpServletRequest httpServletRequest, NotLoginException nle) {

        // 打印堆栈，以供调试
        nle.printStackTrace();

        if(nle.getType().equals(NotLoginException.NOT_TOKEN)) {
            return E.err(4000,"未提供登录凭证");
        }
        else if(nle.getType().equals(NotLoginException.INVALID_TOKEN)) {
            return E.err(4002,"登录凭证无效");
        }
        else if(nle.getType().equals(NotLoginException.TOKEN_TIMEOUT)) {
            return E.err(4003,"登录凭证过期,请重新登陆");
        }
        else if(nle.getType().equals(NotLoginException.BE_REPLACED)) {
            //无状态token不可实现
            return E.err(4004,"已被顶下线");
        }
        else if(nle.getType().equals(NotLoginException.KICK_OUT)) {
            //无状态token不可实现
            return E.err(4005,"已被踢下线");
        }
        else {
            return E.err(4001,"未登录");
        }
    }

    @ResponseBody
    @ExceptionHandler(value = Exception.class)
    public Map handlerAllException(HttpServletRequest httpServletRequest, Exception nle) {
        //错误为aop产生的时候进入
        if (nle instanceof java.lang.reflect.UndeclaredThrowableException){
            //判断注解种类(利用反射)
            if (nle.getCause() instanceof RequestLimitException){
                return E.err(4100,nle.getCause().getMessage());
            }

            //没进入上述if就直接出去
        }
        //判断是否有人为修改token的情况
        if (nle instanceof cn.hutool.json.JSONException){
            return E.err(4002,"登录凭证无效");
        }

        log.error(nle.getClass()+" case: "+nle.getCause());
        nle.printStackTrace();
        return E.err(500,nle.getMessage());
    }

}
